﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using TTServer.Messages;
using System.IO;
using System.Threading;
using TTServer.Objects;
using TTServer.Utilities;
using libReadWrite;
using libCommonClass;
using libAsymmetricEncryption;
using libUtilities;
using bmttPPTController.TTServer;
using libInterface;
using TTServer.Controller;
using DrawingScreen.Messages;
using TTClassLibrary;
using TTServer.MessageProcessor;
using TTServer.MessageProcessors;

namespace TTServer
{
    public class GlobalDispatcher
    {
        private static CTaskQueue _taskQueue;

        private static Thread _dispatcherThread;

        private static List<IMessageProcessor> _processors = new List<IMessageProcessor>();

        static GlobalDispatcher()
        {
            InitMessageProcessors();

            _taskQueue = new CTaskQueue();

            _dispatcherThread = new Thread(new ThreadStart(DispatcherThreadFunction));
            _dispatcherThread.Name = "DispathcherThread";
            _dispatcherThread.IsBackground = true;
            _dispatcherThread.Start();
        }

        private static void InitMessageProcessors()
        {
            Add(new MouseMoveMessageProcessor());
            Add(new MouseClickMessageProcessor());

            Add(new PPTNextSlideMessageProcessor());
            Add(new PPTPrevSlideMessageProcessor());

            Add(new PPTStartSlideShowMessageProcessor());
            Add(new PPTEndSlideShowMessageProcessor());

            Add(new FileExploreRequestMessageProcessor());

            Add(new RSAPublicKeyClientMessageProcessor());
            Add(new AdminAuthentificationRequestMessageProcessor());
            Add(new KeyMemberAuthentificationRequestMessageProcessor());
            Add(new NMSAuthentificationRequestMessageProcessor());
            Add(new ResetNMSAuthentificationMessageProcessor());
            Add(new SignOutRequestMessageProcessor());

            Add(new PPTLaunchPowerpointRequestMessageProcessor());
            Add(new PPTQuitPowerpointRequestMessageProcessor());

            Add(new PPTOpenFileRequestMessageProcessor());

            Add(new PPTCloseFileRequestMessageProcessor());
            Add(new PPTCloseAllFilesRequestMessageProcessor());

            Add(new PPTEnableBroadcastingRequestMessagepProcessor());
            Add(new PPTDisableBroadcastingRequestMessageProcessor());

            Add(new DSLoadRequestMessageProcessor());
            Add(new DSSaveRequestMessageProcessor());

            Add(new PPTSlideShowClickMessageProcessor());

            Add(new PPTGoToSlideRequestMessageProcessor());
            Add(new PPTActivateWindowRequestMessageProcessor());

            Add(new PPTBlackScreenRequestMessageProcessor());
            Add(new PPTWhiteScreenRequestMessageProcessor());

            Add(new PPTShowDrawingScreenRequestMessageProcessor());
            Add(new PPTHideDrawingScreenRequestMessageProcessor());

            Add(new PPTMaximizeWindowRequestMessageProcessor());
            Add(new PPTMinimizeWindowRequestMessageProcessor());

            Add(new DSOpenFileRequestMessageProcessor());

            Add(new PPTWindowsRelationshipRequestMessageProcessor());

            Add(new PPTSlideShowDataRequestMessageProcessor());

            Add(new ScreenSizeRequestMessageProcessor());
            
            Add(new FileDetailsRequestMessageProcessor());
            
        }

        public static void Add(IMessageProcessor processor)
        {
            _processors.Add(processor);
        }

        private static void DispatcherThreadFunction()
        {
            CTask task = null;

            while (true)
            {
                try
                {
                    task = _taskQueue.Dequeue();

                    GlobalDispatcher.ProcessTask(task);
                }
                catch
                {

                }
            }
        }

        public static void AddToQueue(CTask task)
        {
            _taskQueue.Enqueue(task);
        }

        public static void ProcessTask(CTask task)
        {
            TTMessage msg = task.message;

            IClientInfoProvider clientInfoProvider = task.clientInfoProvider;

            //Độ ưu tiên cao
            if (msg is CDrawingMessage_Action)
            {
                DrawingScreenManager.GetInstance().ProcessMessage(msg, clientInfoProvider);
                return;
            }

            //Xử lý thông điệp bình thường
            for (int i = 0; i < _processors.Count; i++)
            {
                if (_processors[i].Process(msg, clientInfoProvider))
                {
                    return;
                }
            }

            //////******************************************
            // Send the message to the drawing screen.
            //**********************************************
            DrawingScreenManager.GetInstance().ProcessMessage(msg, clientInfoProvider);
        }
    }// End Class
} // End Namespace
